#include "adc.h"
#include "systick.h"

void adc_init(void)
{
    /* 1. 使能GPIOC和ADC0时钟 */
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_ADC0);

    /* 2. 配置PC0为模拟输入模式 */
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);

    /* 3. ADC复位 */
    adc_deinit();

    /* 4. 配置ADC参数 */
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE); // 单次转换
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);            // 右对齐
    adc_channel_length_config(ADC0, ADC_ROUTINE_CHANNEL, 1);         // 规则通道长度1
    adc_routine_channel_config(ADC0, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_480); // 通道10=PC0

    // 1. 配置外部触发源（随便选一个，不会实际用到）
    adc_external_trigger_source_config(ADC0, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T1_CH1);
    // 2. 禁用外部触发沿
    adc_external_trigger_config(ADC0, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_DISABLE);
    // 3. 软件触发采样
    adc_software_trigger_enable(ADC0, ADC_ROUTINE_CHANNEL);
    /* 5. 使能ADC并校准 */
    adc_enable(ADC0);
    delay_1ms(1);
    adc_calibration_enable(ADC0);
}

/* 软件触发采样并获取PC0电压的ADC值 */
uint16_t adc0_get_pc0_value(void)
{
    adc_software_trigger_enable(ADC0, ADC_ROUTINE_CHANNEL); // 软件触发
    while(!adc_flag_get(ADC0, ADC_FLAG_EOC));               // 等待转换完成
    uint16_t value = adc_routine_data_read(ADC0);           // 读取ADC值
    adc_flag_clear(ADC0, ADC_FLAG_EOC);                     // 清除标志
    return value;
}

float my_adc_to_voltage(uint16_t adc_value, float vref) {
    if (adc_value > 4095) adc_value = 4095;  // 防止溢出
    return ((float)adc_value / 4095.0f) * vref;
}

uint8_t my_float_to_str(float value, char *str_out) {
    int16_t integer_part = (int16_t)value;
    uint16_t decimal_part = (uint16_t)((value - integer_part) * 100 + 0.5f);  // +0.5四舍五入

    // 处理整数部分
    uint8_t idx = 0;
    if (integer_part < 0) {
        str_out[idx++] = '-';
        integer_part = -integer_part;
    }

    // 整数部分转字符串（支持0-999）
    if (integer_part >= 100) {
        str_out[idx++] = (integer_part / 100) + '0';
        integer_part %= 100;
    }
    if (integer_part >= 10) {
        str_out[idx++] = (integer_part / 10) + '0';
        integer_part %= 10;
    }
    str_out[idx++] = integer_part + '0';

    // 小数点和小数部分
    str_out[idx++] = '.';
    if (decimal_part < 10) {
        str_out[idx++] = '0';  // 补零（如 3.05）
    }
    str_out[idx++] = (decimal_part / 10) + '0';
    str_out[idx++] = (decimal_part % 10) + '0';
    str_out[idx] = '\0';  // 字符串结束符

    return idx;  // 返回字符串长度
}